﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using YmtAuth.Common;

namespace YmtAuth.Repository.DapperRepository
{
    public static class _Extend
    {
        public static DynamicParameters ToParamNames<TEntity>(this TEntity o)
        {
            var tmpParameters = ParametersWrapper.Factory;
            TEntity tmpEntity = (TEntity)System.Activator.CreateInstance(typeof(TEntity), true);
            foreach (
                var prop in
                    typeof(TEntity).GetProperties(BindingFlags.GetProperty | BindingFlags.Instance |
                                                   BindingFlags.Public))
            {
                var attribs = prop.GetCustomAttributes(typeof(IgnorePropertyAttribute), true);
                var attr = attribs.FirstOrDefault() as IgnorePropertyAttribute;
                if (attr == null || (attr != null && !attr.Value))
                {
                    tmpParameters.Add(string.Format("@{0}", prop.Name), prop.GetValue(o));
                }
            }
            return tmpParameters.Build();
        }
        public static DynamicParameters ToDapperParameters(this IDictionary<string, object> @where)
        {
            var parameters = new DynamicParameters();
            foreach (var val in @where)
            {
                parameters.Add(val.Key, val.Value);
            }
            return parameters;
        }
        public static DynamicParameters ToDapperParameters(this DynamicParameters @params, IDictionary<string, object> paramsDic)
        {
            foreach (var val in paramsDic)
            {
                @params.Add(val.Key, val.Value);
            }
            return @params;
        }

        public static DynamicParameters ToDapperParameters(this DbParameter[] parameter)
        {
            if (parameter == null) return null;

            var dp = new DynamicParameters();
            foreach (var item in parameter)
                dp.Add(item.ParameterName, item.Value, item.DbType);

            return dp;
        }
       
        public static IEnumerable<TFirst> Map<TFirst, TSecond, TGroupByKey>(
           this SqlMapper.GridReader reader,
           Func<TFirst, TGroupByKey> firstKey,
           Func<TSecond, TGroupByKey> secondKey,
           Action<TFirst, IEnumerable<TSecond>> addChildren
           )
        {
            if (reader.IsConsumed) return new TFirst[0];
            //父对象
            var first = reader.Read<TFirst>();
            if (reader.IsConsumed) return first;
            //子对象
            var childMap = reader
                .Read<TSecond>()
                .GroupBy(s => secondKey(s))
                .ToDictionary(g => g.Key, g => g.AsEnumerable());

            foreach (var item in first)
            {
                IEnumerable<TSecond> children;
                if (childMap.TryGetValue(firstKey(item), out children))
                {
                    addChildren(item, children);
                }
            }
            return first;
        }
    }
}
